using System;
using System.Collections.Generic;
using IQIGame.Onigao.Framework;

namespace IQIGame.Onigao.Logic
{
    public static class TargetSelectFactory
    {
        public static TargetSelect CreateTargetSelectBySkill(Skill rSkill, TargetSelectConfig rSelectConfig)
        {
            if (rSelectConfig == null)
            {
                LogicLog.LogError($"{rSkill.skillID} 未找到目标选择配置");
            }
            var rType = (ETargetSelectType)rSelectConfig.type;
            TargetSelect rSelect = CreateTargetSelect(rType);
            rSelect.Initialize(rSkill.executer, rSelectConfig);
            return rSelect;
        }

        public static TargetSelect CreateTargetSelect(Unit rSelf, ETargetSelectType rType, List<int> rParam)
        {
            TargetSelect rSelect = CreateTargetSelect(rType);
            rSelect.Initialize(rSelf, rParam);
            return rSelect;
        }

        public static SkillCustomConfig CreateTargetSelectConfig(int nType)
        {
            SkillCustomConfig rConfig = null;
            switch ((ETargetSelectType)nType)
            {
                case ETargetSelectType.Circle:
                    rConfig = new TargetSelect_Circle_ConfigData();
                    break;
                case ETargetSelectType.Fan:
                    rConfig = new TargetSelect_Fan_ConfigData();
                    break;
                case ETargetSelectType.Cub:
                    rConfig = new TargetSelect_Cub_ConfigData();
                    break;
                case ETargetSelectType.InputUnit:
                    rConfig = new TargetSelect_InputUnit_ConfigData();
                    break;
                case ETargetSelectType.RandomUnit:
                    rConfig = new TargetSelect_RandomUnit_ConfigData();
                    break;
                default:
                    rConfig = new SkillCustomConfig();
                    break;
            }

            return rConfig;
        }

        private static TargetSelect CreateTargetSelect(ETargetSelectType rType)
        {
            TargetSelect rSelect;
            switch (rType)
            {
                case ETargetSelectType.InputUnit:
                    rSelect = ClassPool.Get<TargetSelect_InputUnit>();
                    break;
                case ETargetSelectType.RandomUnit:
                    rSelect = ClassPool.Get<TargetSelect_RandomUnit>();
                    break;
                case ETargetSelectType.Circle:
                    rSelect = ClassPool.Get<TargetSelect_Circle>();
                    break;
                case ETargetSelectType.Self:
                    rSelect = ClassPool.Get<TargetSelect_Self>();
                    break;
                case ETargetSelectType.Fan:
                    rSelect = ClassPool.Get<TargetSelect_Fan>();
                    break;
                case ETargetSelectType.Cub:
                    rSelect = ClassPool.Get<TargetSelect_Cub>();
                    break;
                case ETargetSelectType.LastHitSelf:
                    rSelect = ClassPool.Get<TargetSelect_LastHitSelf>();
                    break;
                case ETargetSelectType.All:
                    rSelect = ClassPool.Get<TargetSelect_All>();
                    break;
                default:
                    throw new Exception($"必须指定目标选择类型 : {rType}");
            }
            return rSelect;
        }
    }

    public static class TargetSelectUtil
    {
        public static void GetAllTargetsByRelation(Unit rSelf, ETargetRelation rRealtion, ref List<Unit> rTarget)
        {
            var rCurTeamIndex = rSelf.teamIndex;
            if ((rRealtion & ETargetRelation.Friend) > 0)
            {
                var rTargetIndex = BattleTeam.GetTargetTeamIndex(rCurTeamIndex, ETargetRelation.Friend);
                var rTeamUnits = rSelf.battle.playCtrl.teamCtrl.teams[rTargetIndex].units;
                for (int i = 0; i < rTeamUnits.Count; i++)
                {
                    var rUnit = rTeamUnits[i];
                    if (!rUnit.IsDead() && !rUnit.IsTotem() && rTeamUnits[i] != rSelf)
                    {
                        rTarget.Add(rTeamUnits[i]);
                    }
                }
            }
            if ((rRealtion & ETargetRelation.Self) > 0)
            {
                rTarget.Add(rSelf);
            }

            if ((rRealtion & ETargetRelation.Enemy) > 0)
            {
                var rTargetIndex = BattleTeam.GetTargetTeamIndex(rCurTeamIndex, ETargetRelation.Enemy);
                var rTeamUnits = rSelf.battle.playCtrl.teamCtrl.teams[rTargetIndex].units;
                for (int i = 0; i < rTeamUnits.Count; i++)
                {
                    var rUnit = rTeamUnits[i];
                    if (!rUnit.IsDead() && !rUnit.IsTotem() && rTeamUnits[i] != rSelf)
                    {
                        rTarget.Add(rTeamUnits[i]);
                    }
                }
            }
        }
    }
}